// RAP [bm]: animations
///*******************************************************************************
// * Copyright (c) 2004, 2010 IBM Corporation and others.
// * All rights reserved. This program and the accompanying materials
// * are made available under the terms of the Eclipse Public License v1.0
// * which accompanies this distribution, and is available at
// * http://www.eclipse.org/legal/epl-v10.html
// *
// * Contributors:
// *     IBM Corporation - initial API and implementation
// *******************************************************************************/
//package org.eclipse.ui.internal;
//
//import org.eclipse.core.runtime.IProgressMonitor;
//import org.eclipse.core.runtime.IStatus;
//import org.eclipse.core.runtime.Status;
//import org.eclipse.core.runtime.jobs.Job;
//import org.eclipse.jface.preference.IPreferenceStore;
//import org.eclipse.jface.util.Geometry;
//import org.eclipse.swt.graphics.Rectangle;
//import org.eclipse.swt.widgets.Control;
//import org.eclipse.swt.widgets.Display;
//import org.eclipse.swt.widgets.Shell;
//import org.eclipse.ui.IWorkbenchPreferenceConstants;
//import org.eclipse.ui.internal.util.PrefUtil;
//
///**
// * This job creates an animated rectangle that moves from a source rectangle to
// * a target in a fixed amount of time. To begin the animation, instantiate this
// * object then call schedule().
// *  
// * @since 3.0
// */
//public class RectangleAnimation extends Job {
//	private static class AnimationFeedbackFactory {
//		public static DefaultAnimationFeedback createAnimationRenderer(Shell parentShell) {
//			return new DefaultAnimationFeedback();
//		}
//	}
//	
//	// Constants
//	public static final int TICK_TIMER = 1;
//	public static final int FRAME_COUNT = 2;
//
//	// Animation Parameters
//	private Display display;
//	
//	private boolean enableAnimations;
//    private int timingStyle = TICK_TIMER;
//    private int duration;
//    
//    // Control State
//    private DefaultAnimationFeedback feedbackRenderer;
//    private long stepCount;
//    private long frameCount;
//    private long startTime;
//    private long curTime;
//    private long prevTime;
//    
//    // Macros
//    private boolean done() { return amount() >= 1.0; }
//
//    public static Rectangle interpolate(Rectangle start, Rectangle end,
//            double amount) {
//        double initialWeight = 1.0 - amount;
//
//        Rectangle result = new Rectangle((int) (start.x * initialWeight + end.x
//                * amount), (int) (start.y * initialWeight + end.y * amount),
//                (int) (start.width * initialWeight + end.width * amount),
//                (int) (start.height * initialWeight + end.height * amount));
//
//        return result;
//    }
//    
//    // Animation Step
//    private Runnable animationStep = new Runnable() {
//
//		public void run() {
//            // Capture time
//            prevTime = curTime;
//            curTime = System.currentTimeMillis();
//
//            // Has the system timer 'ticked'?
//            if (curTime != prevTime) {
//            	clockTick();
//            }
//            
//            if (isUpdateStep()) {
//	            updateDisplay();
//	            frameCount++;
//            }
//            
//            stepCount++;
//        }
//
//    };
//    
//	/**
//     * Creates an animation that will morph the start rectangle to the end rectangle in the
//     * given number of milliseconds. The animation will take the given number of milliseconds to
//     * complete.
//     * 
//     * Note that this is a Job, so you must invoke schedule() before the animation will begin 
//     * 
//     * @param whereToDraw specifies the composite where the animation will be drawn. Note that
//     * although the start and end rectangles can accept any value in display coordinates, the
//     * actual animation will be clipped to the boundaries of this composite. For this reason,
//     * it is good to select a composite that encloses both the start and end rectangles.
//     * @param start initial rectangle (display coordinates)
//     * @param end final rectangle (display coordinates)
//     * @param duration number of milliseconds over which the animation will run 
//     */
//    public RectangleAnimation(Shell parentShell, Rectangle start,
//            Rectangle end, int duration) {
//        super(WorkbenchMessages.RectangleAnimation_Animating_Rectangle);
//
//        // if animations aren't on this is a NO-OP
//        IPreferenceStore preferenceStore = PrefUtil.getAPIPreferenceStore();
//        enableAnimations = preferenceStore.getBoolean(IWorkbenchPreferenceConstants.ENABLE_ANIMATIONS);
//        
//        if (!enableAnimations) {
//        	return;
//        }
//
//        // Capture paraeters
//        display = parentShell.getDisplay();
//        this.duration = duration;
//
//        // Don't show the job in monitors
//        setSystem(true);
//        
//        // Pick the renderer (could be a preference...)
//        feedbackRenderer = AnimationFeedbackFactory.createAnimationRenderer(parentShell);
//        
//        // Set it up
//        feedbackRenderer.initialize(parentShell, start, end);
//        
//        // Set the animation's initial state
//        stepCount = 0;
//        //long totalFrames = (long) ((duration / 1000.0) * framesPerSec);       
//        curTime = startTime = System.currentTimeMillis();
//    }
//
//    public RectangleAnimation(Shell parentShell, Rectangle start, Rectangle end) {
//        this(parentShell, start, end, 400);
//    }
//    
//    public void addStartRect(Rectangle rect) {
//    	if (feedbackRenderer != null)
//    		feedbackRenderer.addStartRect(rect);
//    }
//    
//    public void addEndRect(Rectangle rect) {
//    	if (feedbackRenderer != null)
//    	    feedbackRenderer.addEndRect(rect);
//    }
//
//    public void addStartRect(Control ctrl) {
//    	Rectangle ctrlBounds = ctrl.getBounds();
//    	Rectangle startRect = Geometry.toDisplay(ctrl.getParent(), ctrlBounds);
//    	addStartRect(startRect);
//    }
//
//    public void addEndRect(Control ctrl) {
//    	Rectangle ctrlBounds = ctrl.getBounds();
//    	Rectangle endRect = Geometry.toDisplay(ctrl.getParent(), ctrlBounds);
//    	addEndRect(endRect);
//    }
//
//    /**
//	 * 
//	 */
//	protected void clockTick() {
//	}
//    
//    /**
//	 * @return
//	 */
//	protected boolean isUpdateStep() {
//		switch (timingStyle) {
//			case TICK_TIMER:
//				return prevTime != curTime;
//	
//			case FRAME_COUNT:
//				return true;
//		}
//		
//		return false;
//	}
//
//	private double amount() {
//		double amount = 0.0;
//		
//		switch (timingStyle) {
//			case TICK_TIMER:
//				amount = (double) (curTime - startTime) / (double) duration;
//				break;
//	
//			case FRAME_COUNT:
//				amount = (double)frameCount / (double)duration;
//		}
//		
//		if (amount > 1.0)
//			amount = 1.0;
//		
//		return amount;
//    }
//
//    /**
//	 * 
//	 */
//	protected void updateDisplay() {
//		feedbackRenderer.renderStep(amount());
//	}
//
//	/* (non-Javadoc)
//     * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
//     */
//    protected IStatus run(IProgressMonitor monitor) {
//    	
//        // We use preference value to indicate that the animation should be skipped on this platform.
//        if (!enableAnimations || feedbackRenderer == null) {
//            return Status.OK_STATUS;
//        }
//
//        // Do we have anything to animate ?
//    	boolean isEmpty = feedbackRenderer.getStartRects().size() == 0;
//        if (isEmpty) {
//            return Status.OK_STATUS;
//        }
//    	
//        // We're starting, initialize
//        display.syncExec(new Runnable() {
//            public void run() {
//                feedbackRenderer.jobInit();
//            }
//        });
//        
//        // Only start the animation timer -after- we've initialized
//        curTime = startTime = System.currentTimeMillis();
//        
//        while (!done()) {
//            display.syncExec(animationStep);
//            // Don't pin the CPU
//            Thread.yield();
//        }
//
//        //System.out.println("Done: " + (curTime-startTime) + " steps: " + stepCount + " frames:" + frameCount);   //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
//        // We're done, clean up
//        display.syncExec(new Runnable() {
//            public void run() {
//                feedbackRenderer.dispose();
//            }
//        });
//    
//        return Status.OK_STATUS;
//    }
//}
